package com.smart.service.impl;

import java.util.Map;
import java.util.ArrayList;
import java.util.List;
import com.smart.entity.SysDept;
import com.smart.vo.TreeSelect;
import java.util.stream.Collectors;
import com.smart.service.DeptService;
import com.smart.common.enums.StatusEnums;
import org.springframework.stereotype.Service;
import com.smart.common.exception.ApiException;
import com.smart.common.exception.SysExceptionEnum;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

/**
 * @author lgb
 * @date 2020年6月11日 下午4:44:26
 * Copyright (C) 深圳工勘科技
 * @说明: 部门serviceImpl
 **/
@Service
public class DeptServiceImpl extends BaseServiceImpl<SysDept,Long>
           implements DeptService{

	/**
     * 查询部门管理数据
     * @param params 部门信息
     * @return 部门信息集合
     **/
	@Override
	public List<SysDept> selectDeptList(Map<String,Object> params) {
		LambdaQueryWrapper<SysDept> wrapper = new LambdaQueryWrapper<>();
        wrapper.apply(params.get("") != null,
        		(String) params.get(""));
        return list(wrapper);
	}

	/** 
	 * (non-Javadoc)
	 * @see:根据id查询实体
	 **/
	@Override
	@Transactional(readOnly=true)
	public SysDept selectById(Long id) {
		return this.baseMapper.selectById(id);
	}

	/** 
	 * (non-Javadoc)
	 * @see: 编辑部门信息
	 **/
	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public int update(Long id, SysDept dept) {
		dept.setId(id);
		dept.setAncestors(getAncestors(dept.getPid()));
	    return this.baseMapper.updateById(dept);
	}
	
	/**
     * 获取祖级列表
     * @param pid
     * @return
     **/
    private String getAncestors(Long pid) {
        // 查询父级菜单 ParentId 信息
        SysDept dept = this.baseMapper.selectById(pid);
        if (dept == null || StatusEnums.DISABLE.getKey().equals(dept.getStatus())) {
            throw new ApiException(SysExceptionEnum.DEPT_NOT_EXISTS);
        }
        return dept.getAncestors() + "," + pid;
    }

	@Override
	@Transactional(rollbackFor=RuntimeException.class)
	public List<TreeSelect> buildDeptTreeSelect(List<SysDept> depts) {
		List<SysDept> deptTrees = buildDeptTree(depts);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
	}
	
	/**
	 * 构建前端所需要树结构
	 * @param depts 部门列表
	 * @return 树结构列表
	 **/
	private List<SysDept> buildDeptTree(List<SysDept> depts) {
		List<SysDept> returnList = new ArrayList<>();
		List<Long> tempList = new ArrayList<>();
		for (SysDept dept : depts) {
			tempList.add(dept.getId());
		}
		for (SysDept dept : depts) {
			// 如果是顶级节点, 遍历该父节点的所有子节点
			if (!tempList.contains(dept.getPid())) {
				recursionFn(depts, dept);
				returnList.add(dept);
			}
		}
		if (returnList.isEmpty()) {
			returnList = depts;
		}
		return returnList;
	}
	/** 递归列表 */
    private void recursionFn(List<SysDept> list, SysDept t) {
        // 得到子节点列表
        List<SysDept> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysDept tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                for (SysDept n : childList) {
                    recursionFn(list, n);
                }
            }
        }
    }
    
    /** 判断是否有子节点 */
    private boolean hasChild(List<SysDept> list, SysDept t) {
        return getChildList(list, t).size() > 0;
    }

    /** 得到子节点列表 */
    private List<SysDept> getChildList(List<SysDept> list, SysDept t) {
        List<SysDept> tlist = new ArrayList<>();
        for (SysDept n : list) {
            if (n.getPid().longValue() == t.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

	@Override
	public int create(SysDept sysDept) {
		sysDept.setAncestors(getAncestors(sysDept.getPid()));
        return this.baseMapper.insert(sysDept);
	}

	@Override
	public int delete(Long id) {
		return this.baseMapper.deleteById(id);
	}
}